package com.sun.huazhi.aitaskservice.common.client;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpStatus;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

@Component
public class PythonVideoApiClient extends BasePythonApiClient {


    // 可配置参数
    private final Duration apiTimeout = Duration.ofSeconds(30);
    private final int maxRetries = 3;
    private final long retryDelay = 1000;

    /**
     * WebClient：用于异步地向 Python API 发起请求。
     * apiKey / baseUrl：通过配置文件注入，实现解耦。
     * tempDir：为临时视频文件创建一个独立的存储目录，避免冲突。
     * @throws IOException
     */
    public PythonVideoApiClient(
            @Value("${python.video-api.url}") String baseUrl,
            @Value("${python.video-api.key:{cipher}encryptedValueHere}") String apiKey,
            @Value("${temp.file.dir}") String tempDirPath) throws IOException {

        super(baseUrl, apiKey , tempDirPath , "videos");

    }

    /**
     * 调用接口生成视频
     * 成功后：接收视频数据流并保存在本地临时文件（saveToTempFile）；最终返回该文件对象。
     */
    @Retryable(
            include = {RetryableException.class},
            maxAttempts = maxRetries,
            backoff = @Backoff(delay = retryDelay)
    )
    public File generateVideoFile(String prompt) {
        return webClient.post()
                .uri("/create-video")
                .bodyValue(createRequest(prompt))
                .retrieve()
                .onStatus(
                        httpStatus -> httpStatus.is5xxServerError(),
                        response -> Mono.error(new RetryableException("服务器错误: " + response.statusCode()))
                )
                .onStatus(
                        httpStatus -> httpStatus.is4xxClientError(),
                        response -> {
                            if (response.statusCode() == HttpStatus.TOO_MANY_REQUESTS) {
                                return Mono.error(new RetryableException("请求过多"));
                            } else {
                                return Mono.error(new NonRetryableException("客户端错误: " + response.statusCode()));
                            }
                        }
                )
                .bodyToMono(Resource.class)
                .map(this::saveToTempFile)
                .block(apiTimeout);
    }

    // 使用显式构造 Map
    private Map<String, Object> createRequest(String prompt) {
        Map<String, Object> request = new HashMap<>();
        request.put("text", prompt);
        request.put("duration", 10);
        return request;
    }

    private File saveToTempFile(Resource resource) {
        try {
            Path tempFile = tempDir.resolve("video-" + System.nanoTime() + ".mp4");
            Files.copy(resource.getInputStream(), tempFile,
                    StandardCopyOption.REPLACE_EXISTING);
            return tempFile.toFile();
        } catch (IOException e) {
            throw new NonRetryableException("文件保存失败", e);
        }
    }

    private Path createTempDirectory(String basePath) throws IOException {
        return Files.createTempDirectory(Path.of(basePath), "video-");
    }

    // 自定义异常类
    public static class RetryableException extends RuntimeException {
        public RetryableException(String message) {
            super(message);
        }
    }

    public static class NonRetryableException extends RuntimeException {
        public NonRetryableException(String message, Throwable cause) {
            super(message, cause);
        }
        public NonRetryableException(String message) {
            super(message);
        }
    }
}